
#include "gfs_api.h"


//#include "gfs.h"
//#include "gfs_util.h"
//#include "MercuryThread.h"
//#include "MercuryAudio.h"
//#include "MercuryCSTD.h"

#ifdef GTREE_FILE_COURCE

//#define FILE_COMPEN_4BYTE

int gfs_SaveGuide(gFILE pfd,int gLen)
{
	u16 save_IndexEntry,IndexHead;
	if(pfd->flagUp & (G_UP_H_NEW|G_UP_H_OLD)) {
		save_IndexEntry = pfd->IndexEntry;
		if((pfd->flagUp & G_UP_H_NEW) && pfd->flagNew != 1)
			IndexHead = GFS_INDEX_NULL;
		else //if(pfd->flagNew == 1)
			IndexHead = save_IndexEntry;
		if(gLen > sizeof(pfd->u))
			gLen = sizeof(pfd->u);
		
		while(1) {
			if(IndexHead == GFS_INDEX_NULL) {
				IndexHead = gfs_get_next_nullblock();
				if(IndexHead == GFS_INDEX_NULL) {
					if(save_IndexEntry == GFS_INDEX_NULL)
						break;
					gfs_FsEraseblock(save_IndexEntry);	//写入失败察除再写入
					gfs_unrecord_erase(save_IndexEntry);
					LG("***Write Hear old_Index[%d]",save_IndexEntry);
					IndexHead=save_IndexEntry;
					save_IndexEntry = GFS_INDEX_NULL;
				}
			}
			//------------Write Head------------------------------------
			if(gfs_FsWriteblock(IndexHead,0,&pfd->u,gLen) == gLen) {
				break;
			}
			#ifdef GTREE_FILE_ERR_RECORD
			SaveHearErr++;
			#endif
			LG("***Write Head Err[%d->%d] flagNew[%d][%X]\r\n",save_IndexEntry,IndexHead,pfd->flagNew,pfd->fOpenFlag);
			//-----------写失败后处理------------------
			gfs_record_erase(IndexHead);
			IndexHead = GFS_INDEX_NULL;
			pfd->flagUp |= G_UP_E_ARB;
		}
		save_IndexEntry = pfd->IndexEntry;
		if(save_IndexEntry != IndexHead) {
			gfs_record_erase(save_IndexEntry);
			pfd->IndexEntry = IndexHead;
			pfd->flagUp |= G_UP_E_ARB;
			pfd->flagNew = 1;
		}
		if(pfd->flagNew == 1) {
			#ifdef GFS_MEDIAN_SCAN
			if(gfs_median_block_loadnew(&pfd->IndexGuide,save_IndexEntry,IndexHead,pfd->u.h.name.filepath))
				pfd->flagUp |= G_UP_G_NEW;
			else
				pfd->flagUp |= G_UP_G_OLD;
			#else
			if(Gfs_LoadIndexGuide(pfd->IndexGuide,IndexHead))
				pfd->flagUp |= G_UP_G_NEW;
			else
				pfd->flagUp |= G_UP_G_OLD;
			#endif
		}
		pfd->flagNew = 0;
		if(IndexHead == GFS_INDEX_NULL) { //文件头存无法存储--文件所有内容必需清空
			LG("#####NOSPC close ERR file[%s] IndexEntry[%d]\r\n",pfd->u.h.name.filepath,save_IndexEntry);
			//pfd->flagUp |= G_UP_E_ARB;
			return GFS_ERR_NOSPC;
		}
	}
	if(pfd->flagUp & (G_UP_G_NEW|G_UP_G_OLD)) {
		gfs_balanced_global_save(pfd->flagUp&G_UP_G_NEW);
	}
	if(pfd->flagUp & G_UP_E_ARB) {
		gfs_check_erase_block_bit(1);
	}
	pfd->flagUp = G_UP_NULL;
    return GFS_OK;
}


gFILE gfs_open(const char *path, int flags ,...)
{
	int num = 0, mLen = 0;
	#ifdef GFS_RECORD_FUNTION
	if(flags&GFS_O_COUNT)
	{//------check-----
		va_list arg;
		va_start( arg, flags );
		mLen = va_arg(arg, int);
		num = va_arg(arg, int);
		va_end( arg );
		if(mLen > (GFS_BLOCK_SIZE-sizeof(DfgHeadCheck))) {
			SZ_LOG(LOG_ERROR,"gfs CREAT cot len(%d) is tobig\r\n",mLen);
			return NULL;
		}
	}
	#endif
	{
		gFILE pfd;
		u16 index,InBlock;
		gFsNameUnit gfsName;
		index = (u16)strlen(path);	//借用index
		if(index < 1 && index >= offsize(DfGTreeFsFileName,filepath)) {
			LG_HEX("##filepath is Err",(u8*)path,32);
			return NULL;
		}
		index=gfs_ScanFileName(&gfsName,path);	//,GFS_TYPE_BIN
		if(index != GFS_INDEX_NULL) {
			InBlock = gfs_get_block_index(index);
			if(InBlock == GFS_INDEX_NULL) {
				LG("##GetBlockIndex InBlock is Err\r\n");
				return NULL;
			}
			#ifdef GFS_RECORD_FUNTION
			if(gfsName.a.fType == GFS_TYPE_COT) {
				if(flags&GFS_O_COUNT) { //------check-----
					if(gfsName.a.blockNum >= (u16)ARRAY_NUM(pfd->a.h.fdIndex) \
						|| gfsName.a.parLen != (u16)mLen || gfsName.a.PageMax < (u16)num)
					{
						LG("##Record In[%d,%d]->save[%d,%d,%d] Err\r\n",num,mLen,gfsName.a.blockNum,gfsName.a.parLen,gfsName.a.PageMax);
						return NULL;
					}
				}
				else { //不正确的文件打开方式，不允许读写操作
					flags &= ~GFS_O_RDWR;
				}
				//----------------------------------------------
				pfd=(gFILE)malloc((sizeof(tFILE) - offsize(tFILE,a.d)) + gfsName.a.pgSize); 
				if(pfd == NULL) {
					LG("gfs open COUNT malloc gFILE is not\r\n");
					return NULL;
				}
				memset_u32((u32*)&pfd->a.d,0xFFFFFFFF,gfsName.a.pgSize/sizeof(u32));
				#ifdef FILE_COMPEN_4BYTE //4byte 补偿
				gfs_FsReadblock(InBlock,sizeof(pfd->a.h.name),pfd->a.h.fdIndex,DfGetBeiSu((sizeof(pfd->a.h.fdIndex[0])*gfsName.a.blockNum),4));
				#else	//--正常操作
				gfs_FsReadblock(InBlock,sizeof(pfd->a.h.name),pfd->a.h.fdIndex,sizeof(pfd->a.h.fdIndex[0])*gfsName.a.blockNum);
				#endif
				//---- 补充End标签------------
				if(gfsName.a.blockNum < ARRAY_NUM(pfd->a.h.fdIndex))
					pfd->a.h.fdIndex[gfsName.a.blockNum] = GFS_INDEX_NULL;
				memcpy_u32((u32*)&pfd->a.h.name,(u32*)&gfsName.a,sizeof(pfd->a.h.name)/sizeof(u32));
				gfs_RecordNewSearch(&pfd->a.h);
				pfd->IndexGuide = index;
				pfd->IndexEntry = InBlock;
				pfd->fOpenFlag = flags;
				pfd->flagUp = G_UP_NULL;
				pfd->flagNew = 0;
				return pfd;
			}
			else
			#endif
			{
				if(F_CHECK_WR(flags)) {
					pfd=(gFILE)malloc(sizeof(tFILE));
					if(pfd == NULL) {
						LG("gfs open WR malloc[%d] is not\r\n",sizeof(tFILE));
						return NULL;
					}
					gfs_FsReadblock(InBlock,sizeof(gfsName.f),((u8*)&pfd->u)+sizeof(gfsName.f),sizeof(pfd->u)-sizeof(gfsName.f));
				}
				else { //GFS_O_RDONLY
					mLen = REV_ENCOD(gfsName.f.InvLen);
					//----多加一个 fdIndex 空间GFS_INDEX_NULL 用于结束循环-----
					num = 0;
					#if(GTREE_FS_UNIT_SIZE < GFS_BLOCK_SIZE)
					mLen -= sizeof(pfd->u.fData);
					#endif
					while(mLen > 0) {
						mLen -= GFS_BLOCK_SIZE;
						num += sizeof(pfd->u.h.fdIndex[0]);
					}
					pfd =(gFILE)malloc(num + (sizeof(tFILE)- sizeof(pfd->u) + sizeof(pfd->u.h.name)) + sizeof(pfd->u.h.fdIndex[0])); 
					if(pfd == NULL) {
						LG("gfs open RDONLY malloc[%d+x] is not\r\n",num);
						return NULL;
					}
					if(num > 0) {
						#ifdef FILE_COMPEN_4BYTE	//4byte 补偿
						gfs_FsReadblock(InBlock,sizeof(gfsName.f),((u8*)&pfd->u)+sizeof(gfsName.f),DfGetBeiSu(num,4));
						#else //--正常模式
						gfs_FsReadblock(InBlock,sizeof(gfsName.f),((u8*)&pfd->u)+sizeof(gfsName.f),num);
						#endif
					}
					if(num < sizeof(pfd->u.h.fdIndex)) {//- GFS_O_RDONLY 模式下补充End标签----
						pfd->u.h.fdIndex[num/sizeof(pfd->u.h.fdIndex[0])] = GFS_INDEX_NULL;
					}
				}
				memcpy_u32((u32*)&pfd->u.h.name,(u32*)&gfsName.f,sizeof(gfsName.f)/sizeof(u32));
				pfd->IndexGuide = index;
				pfd->IndexEntry = InBlock;
				pfd->fOpenFlag = flags;
				pfd->flagUp = G_UP_NULL;
				pfd->flagNew = 0;
				pfd->fLen= REV_ENCOD(gfsName.f.InvLen);
				if(flags&GFS_O_APPEND) {
					gfs_SetOffset(pfd,0,GFS_SEEK_END);
					pfd->flagNew = 4;
				}
				else {
					if((flags&GFS_O_TRUNC) && pfd->fLen>0) {
						pfd->fLen = 0;
						pfd->flagNew = 2;
					}
					pfd->fOffset = 0;
					#if(GFS_BLOCK_SIZE > GTREE_FS_UNIT_SIZE)
					pfd->IndexB = 0;
					pfd->bOffet = sizeof(pfd->u.h);
					#else
					pfd->IndexB = 1;
					pfd->bOffet = 0;
					#endif
				}
				return pfd;
			}
		}
		if(flags&GFS_O_CREAT) {
			index=gfs_get_new_guide();
			if(index != GFS_INDEX_NULL) {
				InBlock = gfs_get_next_nullblock();
				if(InBlock != GFS_INDEX_NULL) {
					#ifdef GFS_RECORD_FUNTION
					if(flags&GFS_O_COUNT) {
						int buffLen= (sizeof(tFILE) - offsize(tFILE,a.d)) + DfGetBeiSu((mLen+sizeof(DfgHeadCheck)),GFS_PAGE_SIZE);
						pfd =(gFILE)malloc(buffLen); //-------申请对应大小空间---------------
						if(pfd == NULL) {
							SZ_LOG(LOG_ERROR,"gfs Retrievefiles2 malloc(%d) is not\r\n",buffLen);
							gfs_free_index_guide(index,InBlock);
							return NULL;
						}
						memset_u32((u32*)&pfd->a,0xFFFFFFFF,(buffLen-((sizeof(tFILE)-sizeof(pfd->a))))/sizeof(u32));
						strcpy(pfd->a.h.name.filepath,(char*)path);
						pfd->a.h.name.fType = GFS_TYPE_COT;
						if(gfs_RecordSpaceInit(&pfd->a.h,num,mLen)) {
							gfs_free_index_guide(index,InBlock);
							free(pfd);
							return NULL;
						}
						//pfd->a.h.count = 0xffffffff; //--提前固定空间后续write与close不再申请Flash空间---------
						//pfd->a.h.PageIndex = GFS_INDEX_NULL;
						pfd->IndexGuide = index;
						pfd->IndexEntry = InBlock;
						pfd->fOpenFlag = flags;
						//---------写空间标识---------------
						pfd->flagUp = G_UP_G_OLD|G_UP_H_OLD;
						pfd->flagNew = 1;
						if(gfs_SaveGuide(pfd,DfGetBeiSu(pfd->a.h.name.blockNum * sizeof(pfd->a.h.fdIndex[0]) + sizeof(pfd->a.h.name),4))) {
							gfs_ClearFile(pfd->IndexGuide,pfd->IndexEntry,pfd->u.h.fdIndex,ARRAY_NUM(pfd->u.h.fdIndex));
							free(pfd);
							return NULL;
						}
						pfd->a.h.count = 0;
						pfd->a.h.PageIndex = 0;
						pfd->flagUp = G_UP_NULL;
						return pfd;
					}
					else
					#endif
					{
						pfd =(gFILE)malloc(sizeof(tFILE));
						if(pfd == NULL) {
							SZ_LOG(LOG_ERROR,"gfs Retrievefiles3 malloc is not\r\n");
							gfs_free_index_guide(index,InBlock);
							return NULL;
						}
						memset_u32((u32*)&pfd->u,0xFFFFFFFF,sizeof(pfd->u)/sizeof(u32));
						strcpy(pfd->u.h.name.filepath,(char*)path);
						pfd->u.h.name.fType = GFS_TYPE_BIN;
						pfd->IndexGuide = index;
						pfd->IndexEntry = InBlock;
						pfd->fOpenFlag = flags;
						pfd->flagUp = G_UP_G_OLD|G_UP_H_OLD;	//申请空间标记
						pfd->fLen = 0;
						pfd->fOffset = 0;
						#if(GFS_BLOCK_SIZE > GTREE_FS_UNIT_SIZE)
						pfd->IndexB = 0;
						pfd->bOffet = sizeof(pfd->u.h);
						#else
						pfd->IndexB = 1;
						pfd->bOffet = 0;
						#endif
						pfd->flagNew = 1;
						return pfd;
					}
				}
				gfs_free_index_guide(index,InBlock);
				SZ_LOG(LOG_ERROR,"gfs apply GetNextNullBlock is not\r\n");
				return NULL;
			}
			SZ_LOG(LOG_ERROR,"gfs Retrievefiles BlockIndex is full\r\n");
		}
	}
	return NULL;
}

int gfs_seek(gFILE pfd,int offset, int whence)
{
	if(pfd==NULL) return -1;
	if((u32)offset > pfd->fLen) return -2;
	return gfs_SetOffset(pfd,offset,whence);
}

int gfs_read(gFILE pfd,void *buff,int size)
{
	int offset;
	u16 bOffset,bMax;
	if(pfd==NULL) return GFS_ERR_DIR;
	#ifdef GFS_RECORD_FUNTION
	if(pfd->fOpenFlag & GFS_O_COUNT) {
		return gfs_RecordRead(&pfd->a,size,buff);
	}
	#endif
	
	if(size > (int)(pfd->fLen - pfd->fOffset))
		size = (int)(pfd->fLen - pfd->fOffset);
	if(size <= 0) return 0;

	bMax = GFS_BLOCK_SIZE - pfd->bOffet;
	bOffset = pfd->bOffet;
	offset = 0;
	while(offset < size) {
		//----------------------check IndexB and fdIndex[pfd->IndexB]-----------------------
		if(pfd->IndexB > ARRAY_NUM(pfd->u.h.fdIndex)) {
			LG("##gfs read IndexB[%d] ERR\r\n",pfd->IndexB);
			return -2;
		}
		//-------------------------------------------------------------------------------
		if(bMax > (size-offset)) 
			bMax = (size-offset);

		if(buff) {
			#if(GTREE_FS_UNIT_SIZE < GFS_BLOCK_SIZE)
			if(pfd->IndexB==0) {	//第一块内容从RAM中读取
				if(bOffset < sizeof(pfd->u.h) || bOffset >= sizeof(pfd->u)) {
					LG("gfs read IndexB=0,bOffset[%d] ERR\r\n",bOffset);
					return -5;
				}
				if (F_CHECK_WR(pfd->fOpenFlag))
					memcpy((u8*)buff+offset,((u8*)&pfd->u)+bOffset,bMax);
				else //只读没有开后面空间，所以只能从Flash读
					gfs_FsReadblock(pfd->IndexEntry,bOffset,(u8*)buff+offset,bMax);
			}
			else if(pfd->u.h.fdIndex[pfd->IndexB - 1] != GFS_INDEX_NULL) {
				gfs_FsReadblock(pfd->u.h.fdIndex[pfd->IndexB - 1],bOffset,(u8*)buff+offset,bMax);
			}
			#else
			if(pfd->u.h.fdIndex[pfd->IndexB] != GFS_INDEX_NULL) {
				gfs_FsReadblock(pfd->u.h.fdIndex[pfd->IndexB],bOffset,(u8*)buff+offset,bMax);
			}
			#endif
			else {
				LG("###gfs read fdIndex[%d] offset[%d][%d]ERR\r\n",pfd->IndexB,offset,bMax);
				return GFS_ERR_NOSPC;
			}
		}
		offset += bMax;
		bOffset += bMax;

		if(bOffset >= GFS_BLOCK_SIZE) {
			bOffset -= GFS_BLOCK_SIZE;
			pfd->IndexB ++;
		}
		bMax = GFS_BLOCK_SIZE;
	}
	pfd->bOffet = bOffset;
	pfd->fOffset += offset;
	return offset;
}

int gfs_write(gFILE pfd,void *buff,int writeLen)
{
	u32 uLen,offset;
	u16 bOffset,sOffset;	//save_Index;
	u16 new_Index,old_Index;
	u16 bMax,saveLen;
	//-----处理中间插入数据-----
	u8 *pSave,*pBlockBuff;

	if(pfd==NULL) return GFS_ERR_DIR;
	if(!F_CHECK_WR(pfd->fOpenFlag))
		return GFS_ERR_NOWR_PER;
	#ifdef GFS_RECORD_FUNTION
	if(pfd->fOpenFlag & GFS_O_COUNT) {
		return gfs_RecordSave(&pfd->a,buff);
	}
	#endif
	if(buff==NULL || writeLen <= 0)
		return GFS_ERR_LEN;
	bOffset = pfd->bOffet;
	bMax = GFS_BLOCK_SIZE - bOffset;
	pBlockBuff=NULL;
	offset = 0;

	while((int)offset < writeLen) {
		//----------------------check IndexB and fdIndex[pfd->IndexB]-----------------------
		if(pfd->IndexB > ARRAY_NUM(pfd->u.h.fdIndex)) {
			LG("gfs write IndexB[%d>%d] full",pfd->IndexB,ARRAY_NUM(pfd->u.h.fdIndex));
			break;
		}
		//-------------------------------------------------------------------------------
		if(bMax > (writeLen-offset))
			bMax = (writeLen-offset);
		if(pfd->IndexB == 0) {
			if(bOffset < sizeof(pfd->u.h) || bOffset >= sizeof(pfd->u)) {
				LG("gfs write IndexB=0,bOffset[%d] ERR\r\n",bOffset);
				break;
			}
			pSave = (u8*)&pfd->u + bOffset;
			if((pfd->fOffset+ offset) < REV_ENCOD(pfd->u.h.name.InvLen)) {
				#ifdef XOR_CHECK_SAVE
				if(Incekxor(pSave,(u8*)buff+offset,bMax))
					pfd->flagUp |= G_UP_H_NEW;
				else
					pfd->flagUp |= G_UP_H_OLD;
				#else
				pfd->flagUp |= G_UP_H_NEW;
				#endif
			}
			else 
				pfd->flagUp |= G_UP_H_OLD;
			memcpy(pSave,(u8*)buff+offset,bMax);
		}
		else { //pfd->IndexB > 0
			new_Index = pfd->u.h.fdIndex[pfd->IndexB-1];
			old_Index = new_Index;
			//old_Index = GFS_INDEX_NULL;
			pSave = (u8*)buff +offset;
			saveLen = bMax;
			sOffset = bOffset;
			if(new_Index != GFS_INDEX_NULL) {
				if(saveLen < GFS_BLOCK_SIZE) {
					uLen = REV_ENCOD(pfd->u.h.name.InvLen);
					if(uLen < pfd->fLen)
						uLen = pfd->fLen;
					if((pfd->fOffset+ offset) < uLen) { //不允许在中间原来的块上写入内容---
						pBlockBuff=(u8*)malloc(GFS_BLOCK_SIZE);
						gfs_FsReadblock(new_Index,0,pBlockBuff,GFS_BLOCK_SIZE);
						#ifdef XOR_CHECK_SAVE
						if(Incekxor(pBlockBuff+sOffset,pSave,saveLen))
						#endif
						{//-------原来空间不满足写入条件--重新换块--------
							memcpy(pBlockBuff+sOffset,pSave,saveLen);
							pSave = pBlockBuff;
							if((pfd->fOffset+ offset+saveLen) < pfd->fLen)
								saveLen = pfd->fLen-(pfd->fOffset+ offset);
							if(saveLen < GFS_BLOCK_SIZE && sOffset > 0)
								saveLen += sOffset;
							if(saveLen > GFS_BLOCK_SIZE)
								saveLen = GFS_BLOCK_SIZE;
							sOffset = 0;
							new_Index = GFS_INDEX_NULL;
						}
					}
				}
				else { //满足全块写入--直接切换块，不需要保存-----
					new_Index = GFS_INDEX_NULL;
				}
			}
			//-------------------------------------------------------
			while(1) {
				if(new_Index == GFS_INDEX_NULL) {
					new_Index = gfs_get_next_nullblock();
					if(new_Index == GFS_INDEX_NULL) {
						if(old_Index == GFS_INDEX_NULL)
							break;
						gfs_FsEraseblock(old_Index);	//写入失败察除再写入
						gfs_unrecord_erase(old_Index);
						new_Index=old_Index;
						LG("***Write Data old_Index[%d]",old_Index);
						old_Index = GFS_INDEX_NULL;
					}
				}
				if(gfs_FsWriteblock(new_Index,sOffset,pSave,saveLen) >= (int)saveLen) {
					break;
				}
				//-----------写失败后处理------------------
				LG("***Write Data Err Index[%d->%d]fLen[%d]offset[%d]saveLen[%d] flagNew[%d]\r\n",old_Index,new_Index,pfd->fLen,pfd->fOffset+offset,saveLen,pfd->flagNew);
				//------------检查是否拷贝原数据块内容-------------------
				if(pBlockBuff == NULL) {//---后补写失败--------------
					uLen = REV_ENCOD(pfd->u.h.name.InvLen);
					if(uLen < pfd->fLen)
						uLen = pfd->fLen;
					if(sOffset >0 || (saveLen< GFS_BLOCK_SIZE &&  (pfd->fOffset+offset+saveLen) < uLen)) { //--提取原来块内容---
						pBlockBuff=(u8*)malloc(GFS_BLOCK_SIZE);
						gfs_FsReadblock(new_Index,0,pBlockBuff,GFS_BLOCK_SIZE);
					}
				}
				if(pBlockBuff != NULL && pSave != pBlockBuff) {
					memcpy(pBlockBuff+sOffset,pSave,saveLen);
					if((pfd->fOffset+ offset+saveLen) < pfd->fLen)
						saveLen = pfd->fLen-(pfd->fOffset+ offset);
					if(saveLen < GFS_BLOCK_SIZE && sOffset > 0)
						saveLen += sOffset;
					if(saveLen > GFS_BLOCK_SIZE)
						saveLen = GFS_BLOCK_SIZE;
					sOffset = 0;
					pSave = pBlockBuff;
				}
				gfs_record_erase(new_Index);
				new_Index = GFS_INDEX_NULL;
				pfd->flagUp |= G_UP_E_ARB;
			}
			if(pBlockBuff) {
				free(pBlockBuff); pBlockBuff=NULL;
			}
			old_Index = pfd->u.h.fdIndex[pfd->IndexB-1];
			if(new_Index != GFS_INDEX_NULL) { //-成功-
				pfd->u.h.fdIndex[pfd->IndexB-1]=new_Index;
				if(old_Index == GFS_INDEX_NULL) { //--新增--
					pfd->flagUp |= G_UP_H_OLD|G_UP_G_OLD;
				}
				else if(old_Index != new_Index) { //--替换--
					gfs_record_erase(old_Index);
					if((new_Index&old_Index) ^ new_Index)
						pfd->flagUp |= G_UP_H_NEW|G_UP_G_OLD|G_UP_E_ARB;
					else
						pfd->flagUp |= G_UP_H_OLD|G_UP_G_OLD|G_UP_E_ARB;
				}
			}
			else { //内容无法存储--
				LG("#####NOSPC write ERR file[%s] IndexB[%d]=%d\r\n",pfd->u.h.name.filepath,pfd->IndexB,old_Index);
				//gfs_unrecord_erase(old_Index);
				break;
			}
		}
		//--------------------------------------------------------------------
		offset += bMax;
		bOffset += bMax;
		if(bOffset >= GFS_BLOCK_SIZE)
		{
			bOffset -= GFS_BLOCK_SIZE;
			pfd->IndexB++;
		}
		bMax = GFS_BLOCK_SIZE;
	}
	pfd->bOffet = bOffset;
	pfd->fOffset += offset;
	if(pfd->fOffset > pfd->fLen)
	{
		pfd->fLen =  pfd->fOffset;
		pfd->flagUp |= G_UP_L_ARB;
	}
    return offset;
}

int gfs_sync(gFILE pfd)				//将文件同步到磁盘
{
	if(pfd==NULL)
		return 0;
	#ifdef GFS_RECORD_FUNTION
	if(pfd->fOpenFlag & GFS_O_COUNT)
		return 0;
	#endif
	if((pfd->fLen > 0) && (pfd->flagUp & G_UP_L_ARB)) {
		u32 oldLen = REV_ENCOD(pfd->u.h.name.InvLen);
		if(pfd->fLen != oldLen) {
 			if(pfd->fLen < oldLen) {//-GFS_O_TRUNC--更新内容没有原来那么长----
				#if(GTREE_FS_UNIT_SIZE < GFS_BLOCK_SIZE)
				int Offset = sizeof(pfd->u.fData);
				if(pfd->fLen > sizeof(pfd->u.fData))
					Offset += DfGetBeiSu(pfd->fLen-sizeof(pfd->u.fData),GFS_BLOCK_SIZE);
				if(Offset < (int)oldLen) {
					int i=0;
					Offset -= sizeof(pfd->u.fData);
					while(Offset > 0) {
						i++;
						Offset -= GFS_BLOCK_SIZE;
					}
					gfs_record_delete(&pfd->u.h.fdIndex[i],ARRAY_NUM(pfd->u.h.fdIndex)-i);
					pfd->flagUp |= G_UP_H_NEW|G_UP_E_ARB|G_UP_G_OLD;
				}
				#else
				int Offset = 0;
				if(Offset < (int)oldLen) {
					int i=0;
					while(Offset > 0) {
						i++;
						Offset -= GFS_BLOCK_SIZE;
					}
					gfs_record_delete(&pfd->u.h.fdIndex[i],ARRAY_NUM(pfd->u.h.fdIndex)-i);
					pfd->flagUp |= G_UP_H_NEW|G_UP_E_ARB|G_UP_G_OLD;
				}
				#endif
			}
			oldLen = REV_ENCOD(pfd->fLen);
			if(oldLen ^ (oldLen & pfd->u.h.name.InvLen))
				pfd->flagUp |= G_UP_H_NEW;
			else
				pfd->flagUp |= G_UP_H_OLD;
			pfd->u.h.name.InvLen = oldLen;
		}
		//pfd->flagUp &= ~G_UP_W_ARB;
	}
	return gfs_SaveGuide(pfd, sizeof(pfd->u.h) + pfd->fLen);
}

int gfs_close(gFILE pfd)
{
	int ret;
	if(pfd==NULL) 
		return -1;
	ret=gfs_sync(pfd);
	if(ret == GFS_ERR_NOSPC || ret == GFS_CRE_NOUSE) {	//ret == GFS_WRT_NOOK || 
		//TRACE("**Close ret[%d,%X],oldlen[%d]newLen[%d]fOpenFlag[%d]",ret,pfd->flagUp,(~pfd->u.h.InvLen),pfd->fLen,pfd->fOpenFlag);
		if(pfd->flagUp & G_UP_E_ARB) {
			LG("****Write Err Clear All\r\n");
			gfs_ClearFile(pfd->IndexGuide,pfd->IndexEntry,pfd->u.h.fdIndex,ARRAY_NUM(pfd->u.h.fdIndex));
		}
		else if(REV_ENCOD(pfd->u.h.name.InvLen)==0) {
			gfs_free_index_guide(pfd->IndexGuide,pfd->IndexEntry);
		}
	}
	free(pfd);
    return ret;
}


int gfs_GetSize(gFILE pfd)
{
	if(pfd==NULL) return GFS_ERR_DIR;
	return pfd->fLen;
}

int gfs_remove(const char *path)
{
	gFILE pfd=gfs_open(path,GFS_O_RDONLY);	//GFS_O_WRONLY->GFS_O_RDONLY 取文件头部分参数
	if(pfd == NULL) return 1;
	gfs_ClearFile(pfd->IndexGuide,pfd->IndexEntry,pfd->u.h.fdIndex,ARRAY_NUM(pfd->u.h.fdIndex));
	free(pfd);
	return 0;
}

int gfs_ReadSize(const char *path)
{	
	gFsNameUnit gfsName;
	if(gfs_ScanFileName(&gfsName,path) != GFS_INDEX_NULL) {
		#ifdef GFS_RECORD_FUNTION
		if(gfsName.a.fType == GFS_TYPE_COT)
			return gfsName.a.parLen;
		#endif
		return REV_ENCOD(gfsName.f.InvLen);
	}
	return -1;	
}

int gfs_rename(const char *oldpath, const char*newpath)
{
	gFILE pfd = gfs_open(oldpath,GFS_O_RDONLY | GFS_O_WRONLY);
	if(pfd == NULL) return -1;
	strcpy(pfd->u.h.name.filepath, newpath);
	pfd->flagUp = G_UP_H_OLD;
	pfd->flagNew = 1;
	//----------------------------------------------------
	gfs_record_erase(pfd->IndexEntry);
	#ifdef GFS_MEDIAN_SCAN
	gfs_free_index_guide(pfd->IndexGuide,pfd->IndexEntry);
	#else
	gfs_free_index_guide(pfd->IndexGuide,GFS_INDEX_NULL);
	#endif
	pfd->IndexEntry = GFS_INDEX_NULL;
	pfd->IndexGuide = GFS_INDEX_NULL;
	int ret = gfs_SaveGuide(pfd, sizeof(pfd->u.h) + pfd->fLen);
	free(pfd);
	return ret;
}


#endif

